package mx.gob.imss.reiman.clientes.service.impl;

import java.net.MalformedURLException;

import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

import mx.gob.imss.reiman.clientes.model.Persona;
import mx.gob.imss.reiman.clientes.model.mensajes.Mensaje;
import mx.gob.imss.reiman.clientes.model.mensajes.MensajeIMP;
import mx.gob.imss.reiman.clientes.service.MensajeriaService;
import mx.gob.imss.reiman.clientes.service.SOAPService;
import noNamespace.GovTalkMessageDocument.GovTalkMessage.GovTalkDetails.GovTalkErrors.Error;

import org.apache.xmlbeans.XmlException;
import org.openuri.RegistrarPAIMPDocument;
import org.openuri.RegistrarPAIMPResponseDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 
 * @author Alberto Dzul Calvillo
 * @version 1.0
 * 
 */
@Service("registroPAService")
public class RegistroPAServiceImpl implements MensajeriaService {
	private static final String nodo = "registrarPAIMPResponse";
	@Autowired
	private SOAPService soapService;

	@Override
	public void enviar(Mensaje mensaje, String endpoint)
			throws MalformedURLException, UnsupportedOperationException,
			XmlException, SOAPException {
		enviar(mensaje, endpoint, false);
	}

	@Override
	public void enviar(Mensaje mensaje, String endpoint, boolean xml)
			throws MalformedURLException, UnsupportedOperationException,
			XmlException, SOAPException {
		RegistrarPAIMPDocument document = RegistrarPAIMPDocument.Factory
				.parse(xml ? mensaje.getXml().toString()
						:getXML(((MensajeIMP) mensaje).getPersona()));
		SOAPMessage response = soapService.enviar(document.getDomNode(),
				endpoint);
		if (response != null) {
			obtenResultados(response, mensaje);
		}
	}

	private void obtenResultados(SOAPMessage response, Mensaje mensaje)
			throws XmlException, SOAPException {
		SOAPBody body = response.getSOAPPart().getEnvelope().getBody();
		NodeList nodeList = body.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); ++i) {
			Node node = nodeList.item(i);
			String localName = node.getLocalName();
			if (nodo.equals(localName)) {
				obtenerDatosDelNodo(node, mensaje);
				break;
			}
		}
	}

	private void obtenerDatosDelNodo(Node node, Mensaje mensaje)
			throws XmlException {
		RegistrarPAIMPResponseDocument document = RegistrarPAIMPResponseDocument.Factory
				.parse(node);
		@SuppressWarnings("deprecation")
		Error[] errores = document.getRegistrarPAIMPResponse()
				.getGovTalkMessage().getGovTalkDetails().getGovTalkErrors()
				.getErrorArray();
		try {
			((MensajeIMP) mensaje).getPersona().setIdee(
					document.getRegistrarPAIMPResponse().getGovTalkMessage()
							.getBody().getPatient().getIdeeArray(0));
		} catch (Exception e) {
			logger.error(e.getMessage());
		} catch (NoSuchMethodError e) {
			logger.error(e.getMessage());
		}
		for (Error error : errores) {
			mensaje.getErrores().add(
					new mx.gob.imss.reiman.clientes.model.Error(error
							.getNumber().toString(), error.getTextArray(0)));
		}
	}

	private String getXML(Persona pa) {
		StringBuilder sb = new StringBuilder();
		sb.append("<registrarPAIMP xmlns='http://www.openuri.org/'>\n");
		sb.append("  <GovTalkMessage xmlns='urn:hl7-org:v3'>\n");
		sb.append("    <EnvelopeVersion>2.0</EnvelopeVersion>\n");
		sb.append("	   <Header>\n");
		sb.append("	     <MessageDetails>\n");
		sb.append("	       <Class>PRPA_RM201301</Class>\n");
		sb.append("	       <Qualifier>HL7Message</Qualifier>\n");
		sb.append("	       <Function>submit</Function>\n");
		sb.append("	       <TransactionID/>\n");
		sb.append("	       <CorrelationID/>\n");
		sb.append("	       <GatewayTimestamp>01:01:01 2011/01/01</GatewayTimestamp>\n");
		sb.append("      </MessageDetails>\n");
		sb.append("	     <SenderDetails>\n");
		sb.append("	       <SenderIP>11.254.16.122</SenderIP>\n");
		sb.append("	       <Authentication>\n");
		sb.append("	         <Method>clear</Method>\n");
		sb.append("	         <Value/>\n");
		sb.append("	       </Authentication>\n");
		sb.append("	       </SenderDetails>\n");
		sb.append("	     <ReceiverDetails>\n");
		sb.append("	       <SenderIP>11.254.16.122</SenderIP>\n");
		sb.append("	       <Authentication>\n");
		sb.append("	         <Method>clear</Method>\n");
		sb.append("	         <Value/>\n");
		sb.append("	       </Authentication>\n");
		sb.append("	     </ReceiverDetails>\n");
		sb.append("	   </Header>\n");
		sb.append("    <GovTalkDetails>\n");
		sb.append("	     <TargetDetails>\n");
		sb.append("	     <Organization>IMSS</Organization>\n");
		sb.append("	   </TargetDetails>\n");
		sb.append("    </GovTalkDetails>\n");
		sb.append("    <Body>\n");
		sb.append("      <MCCI_MT000100 xmlns='urn:hl7-org:v3' xmlns:xsi='http://www.w3.org/2002/XMLSchema-instance' xsi:schemaLocation='urn:hl7-org:v3 MCCI_HD000100.xsd'>\n");
		sb.append("       <versionCode code='" + pa.getCveTipoMensaje()
				+ "'/>\n");
		sb.append("        <interactionId root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getCveTipoServicio() + "' displayable='true'/>\n");
		sb.append("        <profileId root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getNumAplicacion() + "' displayable='true'/>\n");
		sb.append("        <processingCode code='" + pa.getCveRFC() + "'/>\n");
		sb.append("        <patient xmlns='urn:hl7-org:v3' xmlns:xsi='http://www.w3.org/2002/XMLSchema-instance' xsi:schemaLocation='urn:hl7-org:v3 PRPA_HD201301.xsd'>\n");
		sb.append("          <patientPerson>\n");
		sb.append("            <id root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getNss() + "' displayable='true'/>\n");
		sb.append("            <name use='" + pa.getNombre() + "'>\n");
		sb.append("              <given>" + pa.getApellidoMaterno()
				+ "</given>\n");
		sb.append("              <family>" + pa.getApellidoPaterno()
				+ "</family>\n");
		sb.append("            </name>\n");
		sb.append("            <telecom value='" + pa.getTelefono()
				+ "' use='H'/>\n");
		sb.append("            <administrativeGenderCode code='"
				+ pa.getSexo()
				+ "' codeSystem='2.16.840.1.113883.5.1' codeSystemName='AdministrativeGender' displayName='Display name'/>\n");
		sb.append("            <birthTime value='" + pa.getFechaNacimiento()
				+ "'/>\n");
		sb.append("            <addr use='HP'>\n");
		sb.append("              <city>" + pa.getIdMunicipio() + "</city>\n");
		sb.append("              <postalCode>" + pa.getCp() + "</postalCode>\n");
		sb.append("              <streetName>" + pa.getCalle()
				+ "</streetName>\n");
		sb.append("              <houseNumber>" + pa.getNumeroExterior()
				+ "</houseNumber>\n");
		sb.append("              <houseNumberNumeric>" + pa.getNumeroInterior()
				+ "</houseNumberNumeric>\n");
		sb.append("              <additionalLocator>" + pa.getColonia()
				+ "</additionalLocator>\n");
		sb.append("            </addr>\n");
		sb.append("            <asCitizen>\n");
		sb.append("              <id root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getCurp() + "' displayable='true'/>\n");
		sb.append("            </asCitizen>\n");
		sb.append("            <asEmployee>\n");
		sb.append("              <id root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getRfc() + "' displayable='true'/>\n");
		sb.append("            </asEmployee>\n");
		sb.append("            <guardian>\n");
		sb.append("              <id root='2.16.840.1.113883.19.3.2409' extension='' displayable='true'/>\n");
		sb.append("              <effectiveTime value='" + pa.getFechaAccion()
				+ "' inclusive='true'/>\n");
		sb.append("              <guardianMedicalUnit>\n");
		sb.append("                <id root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getUnidad() + "' displayable='true'/>\n");
		sb.append("              </guardianMedicalUnit>\n");
		sb.append("            </guardian>\n");
		sb.append("            <asOtherIDs>\n");
		sb.append("              <id root='2.16.840.1.113883.19.3.2409' extension='"
				+ pa.getAgregadoMedico() + "' displayable='true'/>\n");
		sb.append("            </asOtherIDs>\n");
		sb.append("          </patientPerson>\n");
		sb.append("        </patient>\n");
		sb.append("      </MCCI_MT000100>\n");
		sb.append("    </Body>\n");
		sb.append("  </GovTalkMessage>\n");
		sb.append("</registrarPAIMP>\n");
		return sb.toString();
	}
}